package fileinn

import (
	"encoding/json"
	"log"
	"path/filepath"

	"github.com/boltdb/bolt"
	jsoniter "github.com/json-iterator/go"
)

var (
	DB *bolt.DB
)

func init() {
	db, err := bolt.Open(filepath.Join(SavePath, FileName), 0600, nil)
	if err != nil {
		log.Fatal(err)
	}
	DB = db
	DB.Update(func(tx *bolt.Tx) error {
		// 如果Bucket不存在 将创建
		_, err := tx.CreateBucketIfNotExists(DBBucket)
		if err != nil {
			return err
		}
		return nil
	})
}

// Insert 增加/插入
func Insert(key string, value *File) error {
	return DB.Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket(DBBucket)
		// 判断数据库是否存在该文件
		dv := bucket.Get([]byte(key))
		if len(dv) > 0 {
			return nil
		}
		//不存在的话插入
		str, sjmserr := json.Marshal(value)
		if sjmserr != nil {
			return sjmserr
		}
		return bucket.Put([]byte(key), []byte(str))
	})
}

// Select 查找
func Select(key string) (*File, error) {
	var fileObj *File
	err := DB.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket(DBBucket)
		value := bucket.Get([]byte(key))
		if len(value) <= 0 {
			return nil
		}
		// 解析
		JSON := jsoniter.ConfigCompatibleWithStandardLibrary
		fileObj = &File{}
		jserr := JSON.Unmarshal(value, fileObj)
		if jserr != nil {
			return jserr
		}
		return nil
	})
	return fileObj, err
}

// Delete  删除
func Delete(key string) error {
	return DB.Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket(DBBucket)
		return bucket.Delete([]byte(key))
	})

}

// Update  更新
func Update(key string, value *File) error {
	return DB.Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket(DBBucket)
		str, sjmserr := json.Marshal(value)
		if sjmserr != nil {
			return sjmserr
		}
		return bucket.Put([]byte(key), []byte(str))
	})
}

// IsExist 是否存在
func IsExist(key string) (bool, error) {
	var result string
	err := DB.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket(DBBucket)
		value := bucket.Get([]byte(key))
		result = string(value)
		return nil
	})
	if err != nil {
		return false, err
	}
	if len(result) > 0 {
		return true, nil
	}
	return false, nil

}

// ShowAllFile 查看所有的文件
func ShowAllFile() []*File {
	var filelist []*File
	DB.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket(DBBucket)
		c := bucket.Cursor()
		for k, v := c.First(); k != nil; k, v = c.Next() {
			var fileObj *File
			// 解析
			JSON := jsoniter.ConfigCompatibleWithStandardLibrary
			fileObj = &File{}
			jserr := JSON.Unmarshal(v, fileObj)
			if jserr != nil {
				return jserr
			}
			filelist = append(filelist, fileObj)

		}
		return nil
	})
	return filelist
}
